﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using DataLibrary;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.StaticFiles;
using Web.Models;
using Microsoft.EntityFrameworkCore;
using System.IO;
using Microsoft.AspNetCore.Authorization;
using System.IO.Compression;
using System.Text;
using System.Security.Cryptography;

namespace Web.Controllers
{
    [Route("api/[controller]")]
    [ApiController]
    public class FileController : ControllerBase
    {
        private readonly IHostingEnvironment _hostingEnvironment;
        private readonly UpgradeDbContext _dbContext;

        public FileController(IHostingEnvironment hostingEnvironment, UpgradeDbContext dbContext)
        {
            _hostingEnvironment = hostingEnvironment;
            _dbContext = dbContext;
        }


        [HttpPost]
        public async Task<OperationResult> PostAsync(string AppId, IFormCollection files)
        {
            OperationResult result = new OperationResult();

            var product = _dbContext.Products.FirstOrDefault(x => x.Id == AppId);

            if (product == null)
            {
                result.Mess = "项目不存在,请先添加项目";
                return result;
            }

            string dirPath = _hostingEnvironment.ContentRootPath + "/upload/";

            if (!Directory.Exists(dirPath))
                Directory.CreateDirectory(dirPath);

            string fileNewName = Guid.NewGuid().ToString() + "." + Path.GetExtension(files.Files[0].FileName);
            var filePath = dirPath + fileNewName;
            using (var stream = new FileStream(filePath, FileMode.Create))
            {
                await files.Files[0].CopyToAsync(stream);
            }

            dirPath = _hostingEnvironment.ContentRootPath + "/item/" + product.Name;
            if (!Directory.Exists(dirPath))
                Directory.CreateDirectory(dirPath);

            Encoding.RegisterProvider(CodePagesEncodingProvider.Instance);
            ZipFile.ExtractToDirectory(filePath, dirPath, Encoding.GetEncoding("GB2312"), true);

            foreach (DataLibrary.Entity.FileMagic m in _dbContext.FileMagics.Where(x => x.ProductId == AppId))
            {
                _dbContext.FileMagics.Remove(m);
            }
            await _dbContext.SaveChangesAsync();

            foreach (string f in Directory.GetFiles(dirPath))
            {
                FileInfo info = new FileInfo(f);
                string floder = info.DirectoryName;
                floder = floder.Substring(dirPath.Length, floder.Length - dirPath.Length);
                string _md5 = string.Empty;
                using (MD5CryptoServiceProvider md5 = new MD5CryptoServiceProvider())
                {
                    using (FileStream fs = new FileStream(info.FullName, FileMode.Open, FileAccess.Read, FileShare.Read))
                    {
                        _md5 = BitConverter.ToString(md5.ComputeHash(fs)).Replace("-", "");
                    }
                }

                await _dbContext.FileMagics.AddAsync(new DataLibrary.Entity.FileMagic()
                {
                    Id = Guid.NewGuid().ToString().Replace("-", ""),
                    Name = info.Name,
                    Folder = floder,
                    Route = info.FullName,
                    ProductId = AppId,
                    MD5 = _md5
                });

            }

            foreach (string dir in Directory.GetDirectories(dirPath))
            {
                foreach (string f in Directory.GetFiles(dir))
                {
                    FileInfo info = new FileInfo(f);
                    string floder = info.DirectoryName;
                    floder = floder.Substring(dirPath.Length, floder.Length - dirPath.Length);
                    string _md5 = string.Empty;
                    using (MD5CryptoServiceProvider md5 = new MD5CryptoServiceProvider())
                    {
                        using (FileStream fs = new FileStream(info.FullName, FileMode.Open, FileAccess.Read, FileShare.Read))
                        {
                            _md5 = BitConverter.ToString(md5.ComputeHash(fs)).Replace("-", "");
                        }
                    }

                    await _dbContext.FileMagics.AddAsync(new DataLibrary.Entity.FileMagic()
                    {
                        Id = Guid.NewGuid().ToString().Replace("-", ""),
                        Name = info.Name,
                        Folder = floder,
                        Route = info.FullName,
                        ProductId = AppId,
                        MD5 = _md5
                    });

                }
            }
            if (await _dbContext.SaveChangesAsync() > 0)
                result.Ok = true;

            return result;
        }

        [HttpGet]
        public IActionResult Get(string Id)
        {
            var fileMagic = _dbContext.FileMagics.FirstOrDefault(x => x.Id == Id);

            if (fileMagic != null)
            {
                try
                {
                    string fileExt = Path.GetExtension(fileMagic.Name);
                    var provider = new FileExtensionContentTypeProvider();
                    var contentType = provider.Mappings.FirstOrDefault(x => x.Key.Contains(fileExt));
                    string memi = string.Empty;
                    if (string.IsNullOrEmpty(contentType.Value))
                    {
                        memi = "application/octet-stream";
                    }
                    else
                    {
                        memi = contentType.Value;
                    }
                    return PhysicalFile(fileMagic.Route, memi, fileMagic.Name);
                }
                catch
                {

                }
            }


            return Redirect("/Erro/");
        }
    }
}